package ca.scotthyndman.as2haxe.dom;

import ca.scotthyndman.as2haxe.dom.visitor.IVisitor;

/**
 * Represents a name. A name can either be simple or qualified.
 */
public class ASName extends ASExpression {

	protected static AST ast; // FIXME this is hackish

	/**
	 * Constructs a new instance of ASName
	 * 
	 * @param ast
	 *            The abstract syntax tree that owns this element
	 */
	public ASName(AST ast) {
		super(ast);

		ASName.ast = ast;
	}

	/**
	 * Returns whether this is a simple name.
	 */
	public boolean isSimpleName() {
		return this instanceof ASSimpleName;
	}

	/**
	 * Returns whether this is a qualified name.
	 */
	public boolean isQualifiedName() {
		return this instanceof ASQualifiedName;
	}
	
	// ====== CONVERSION
	
	/**
	 * Converts this name into a field access chain.
	 */
	public ASFieldAccess toFieldAccess() {
		ASFieldAccess fa = new ASFieldAccess(getAST());
		if (isSimpleName()) {
			fa.setName((ASSimpleName) clone());
		} else {
			ASQualifiedName q = (ASQualifiedName) this;
			fa.setName((ASSimpleName) q.getName().clone());
			
			if (q.getQualifier() != null) {
				fa.setExpression(q.getQualifier().toFieldAccess());
			}
		}
		
		return fa;
	}
	
	// ====== CLONE

	/**
	 * Clones the name
	 */
	public Object clone() {
		return null;
	}
	
	// ===== VISITOR

	@Override
	public void accept(IVisitor as2Visitor, boolean recursive) {
		as2Visitor.visit(this);
	}
	
	/**
	 * Gets a name representing a string.
	 * 
	 * @param str
	 * @return
	 */
	public static ASName valueOf(String str) {
		ASName name = null;
		if (str.contains(".")) {
			int idx = str.lastIndexOf('.');
			name = new ASQualifiedName(ast, new ASSimpleName(ast, str
					.substring(idx + 1)));
			((ASQualifiedName) name).setQualifier(ASName.valueOf(str.substring(
					0, idx)));
		} else {
			return new ASSimpleName(ast, str);
		}
		return name;
	}
	
	/**
	 * Gets a name representing by a field access expression.
	 * 
	 * @param fa
	 * @return
	 */
	public static ASName valueOf(ASFieldAccess fa) {
		ASName name = null;
		if (fa.getExpression() instanceof ASFieldAccess) {
			ASFieldAccess cfa = (ASFieldAccess) fa.getExpression();
			
			name = new ASQualifiedName(ast, (ASSimpleName) fa.getName().clone());
			((ASQualifiedName) name).setQualifier(ASName.valueOf(cfa));
		} else {
			return new ASSimpleName(ast, fa.getName().getIdentifier());
		}
		return name;
	}
}
